package com.ky.tms.util;

import cn.hutool.core.util.HexUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

/**
 * 3des加密工具（拷贝demo包里的）
 * @author ZJ
 *
 */
public class DBTripleDesUtil {

	static Logger log = LoggerFactory.getLogger(DBTripleDesUtil.class);

	public static String encrypt(String plaintext) {
		try {
			return HexUtil.encodeHexStr(encrpt(plaintext.getBytes())).toUpperCase();
		} catch (Exception e) {
			log.error("敏感信息加密异常", e);
			return plaintext;
		}
	}

	public static String decrypt(String ciphertext) {
		try {
			return new String(decrpt(HexUtil.decodeHex(ciphertext))).trim();
		} catch (Exception e) {
			log.error("敏感信息解密异常", e);
			return ciphertext;
		}
	}

	private static final String TRIPLE_DES_KEY = "9b311c7a94d0704a7f29e53707b90420dababad398f7df23";

	/**
	 * 3DES加密
	 *
	 * @param data 待加密数据
	 * @return
	 * @throws Exception
	 */
	private static byte[] encrpt(byte[] data) throws Exception {
		DESedeKeySpec deSedeKeySpec = new DESedeKeySpec(HexUtil.decodeHex(TRIPLE_DES_KEY));
		SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede");
		SecretKey secretKey = secretKeyFactory.generateSecret(deSedeKeySpec);
		byte[] ivByte = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 初始向量
		IvParameterSpec ivParameterSpec = new IvParameterSpec(ivByte);
		Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding"); // 加密算法与填充模式
		cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);

		// Zero padding
		int blockSize = cipher.getBlockSize();
		int plaintextLength = data.length;
		if (plaintextLength % blockSize != 0) {
			plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
		}
		byte[] plaintext = new byte[plaintextLength];
		System.arraycopy(data, 0, plaintext, 0, data.length);

		return cipher.doFinal(plaintext);
	}

	/**
	 * 3DES解密
	 *
	 * @param data 待解密数据
	 * @return
	 * @throws Exception
	 */
	private static byte[] decrpt(byte[] data) throws Exception {
		DESedeKeySpec deSedeKeySpec = new DESedeKeySpec(HexUtil.decodeHex(TRIPLE_DES_KEY));
		SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede");
		SecretKey secretKey = secretKeyFactory.generateSecret(deSedeKeySpec);
		byte[] ivByte = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 初始向量
		IvParameterSpec ivParameterSpec = new IvParameterSpec(ivByte);
		Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding"); // 加密算法与填充模式
		cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
		return cipher.doFinal(data);
	}
}
